home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / unsq.pas < prev    next >
Pascal/Delphi Source File  |  1985-06-03  |  5KB  |  169 lines

  1. { unsq file from file in_file to out_file }
  2.  
  3. { This program unsqueezes a file which has been squeezed or compressed }
  4. { to reduce the space required to store it on disk. The program was    }
  5. { converted from the original version written for CP/M in the C        }
  6. { language. This program can be used to unsqueeze files which have     }
  7. { been downloaded from RCP/M systems where almost all files are saved  }
  8. { in this squeezed format.                                             }
  9.  
  10. { The technique used is the Huffman encoding technique which converts  }
  11. { the most common characters in the input file to a compressed bit     }
  12. { stream of data. This program unsqueezes such a Huffman encoded file. }
  13.  
  14. { PUBLIC DOMAIN - Feel free to distribute this program. Do not         }
  15. { distribute it by commercial means or make any charge for this pgm.   }
  16.  
  17. { Version 1.0 - 9/5/82 }
  18.  
  19. { Scott Loftesness - 9/05/82 }
  20.  
  21. {$debug-}
  22. {$list-}
  23. {$include:'a:filkqq.inc'}
  24. {$include:'a:filuqq.inc'}
  25. {$list+}
  26. program unsq(in_file,out_file,output);
  27.   uses filkqq, filuqq;
  28.  
  29. const
  30.     recognize = #ff76;
  31.     numvals = 257;  { max tree size + 1 }
  32.     speof = 256;   { special end of file marker }
  33.     dle = chr(#90);
  34.  
  35. type
  36.     tree = array [0..255,0..1] of word;
  37.  
  38. var in_file, out_file: file of char;
  39.     dnode: tree;
  40.     bpos, i, repct: integer;
  41.     c, inchar: char;
  42.     lastchar: char;
  43.     curin, filecksum: word;
  44.     numnodes: integer;
  45.     origfile: string(14);
  46.     eofin: boolean;
  47.  
  48. { getparm -- get parms from command line }
  49. procedure getparm;
  50. var error: word;
  51.     l: lstring(255);
  52. begin
  53.     error:=ppmuqq(0,adr null,l);
  54.     writeln('This was on the command line:',l)
  55. end; {getparm}
  56.  
  57. { getw - get a word value from the input file }
  58. function getw: word;
  59.     var in1,in2: char;
  60.   begin
  61.     read(in_file,in1);
  62.     read(in_file,in2);
  63.     getw:=byword(in2,in1)
  64.   end; {getw}
  65.  
  66. function getc: char;
  67.   begin
  68.     read(in_file,getc)
  69.   end; {getc}
  70.  
  71. procedure openfiles;
  72.   begin
  73.     reset(in_file);   { open the input file }
  74.     rewrite(out_file); {open the output file }
  75.   end; {openfiles}
  76.  
  77. procedure initialize;
  78.   begin
  79.     openfiles;        { go open the files }
  80.     if recognize<>getw then {check for valid unsqueezed file format }
  81.         abort('Error - file is not a squeezed file',1,0);
  82.     filecksum:=getw;  { get checksum from chars 2 - 3 of file }
  83.     i:=0;
  84.     repct:=0;
  85.     bpos:=99;
  86.     origfile:='              ';           { initialize to blanks }
  87.     eofin:=false;
  88.     repeat
  89.         i:=i+1;
  90.         inchar:=getc;
  91.         if inchar<>chr(0) then
  92.             origfile[i]:=chr(inchar)      { build original file name }
  93.     until inchar=chr(0); { bypass the file name in the header }
  94.     writeln(output,'File: ',origfile,' -> ');
  95.     numnodes:=ord(getw); { get the number of nodes in this files tree }
  96.     if (numnodes<0) or (numnodes>=numvals) then
  97.         abort('Error - File has invalid decode tree size',2,0);
  98.     dnode[0,0]:= -(speof+1);
  99.     dnode[0,1]:= -(speof+1);
  100.     numnodes:=numnodes-1;
  101.     for i:=0 to numnodes do begin
  102.         dnode[i,0]:=getw;
  103.         dnode[i,1]:=getw;
  104.     end; {for}
  105.   end; {initialize}
  106.  
  107. procedure dochar(c:char);
  108.   begin
  109.     write(out_file,c);
  110.   end; {dochar}
  111.  
  112. function getuhuff: char;
  113. var i: integer;
  114.   begin
  115.     i:=0;
  116.     repeat
  117.       bpos:=bpos+1;
  118.       if bpos>7 then begin
  119.         curin:=wrd(getc);
  120.         bpos:=0;
  121.         i:=ord(dnode[i,ord(curin and #0001)]);
  122.       end {if}
  123.       else begin
  124.         curin:=curin div wrd(2);
  125.         i:=ord(dnode[i,ord(curin and #0001)]);
  126.       end; {else}
  127.     until (i<0); {repeat}
  128.     i:=-(i+1);
  129.     if i=speof then begin
  130.        eofin:=true;
  131.        getuhuff:=chr(26)
  132.        end {if}
  133.     else getuhuff:=chr(i);
  134.   end; {getuhuff}
  135.  
  136.  
  137. function getcr: char;
  138. var c: char;
  139.   begin
  140.     if (repct>0) then begin
  141.         repct:=repct-1;
  142.         getcr:=lastchar;
  143.     end {if}
  144.     else begin
  145.         c:=getuhuff;
  146.         if c<>dle then begin
  147.             getcr:=c;
  148.             lastchar:=c;
  149.         end {if}
  150.         else begin
  151.             repct:=ord(getuhuff);
  152.             if repct=0 then getcr:=dle
  153.             else begin;
  154.                 repct:=repct-2;
  155.                 getcr:=lastchar;
  156.             end; {else}
  157.         end; {else}
  158.     end; {else}
  159.   end; {getcr}
  160.  
  161. begin   { main program }
  162.     initialize;
  163.     writeln(output,'Tree loaded sucessfully. Un-squeezing begins...');
  164.     while not(eof(in_file)) or not(eofin) do begin
  165.         c:=getcr;
  166.         dochar(c);
  167.     end; {while}
  168. end. {unsq}
  169.